﻿Imports System
Imports System.Globalization
Imports System.Reflection

Namespace System.Workflow.ComponentModel
    Friend Class ActivityBindPropertyInfo
        Inherits PropertyInfo
        ' Methods
        Public Sub New(ByVal declaringType As Type, ByVal getMethod As MethodInfo, ByVal setMethod As MethodInfo, ByVal propertyName As String, ByVal originalPropertyInfo As PropertyInfo)
            If (declaringType Is Nothing) Then
                Throw New ArgumentNullException("declaringType")
            End If
            If (propertyName Is Nothing) Then
                Throw New ArgumentNullException("propertyName")
            End If
            Me.declaringType = declaringType
            Me.getMethod = getMethod
            Me.setMethod = setMethod
            Me.propertyName = propertyName
            Me.originalPropertyInfo = originalPropertyInfo
        End Sub

        Public Overrides Function GetAccessors(ByVal nonPublic As Boolean) As MethodInfo()
            Return New MethodInfo() { Me.getMethod, Me.setMethod }
        End Function

        Public Overrides Function GetCustomAttributes(ByVal inherit As Boolean) As Object()
            Return New Object(0  - 1) {}
        End Function

        Public Overrides Function GetCustomAttributes(ByVal attributeType As Type, ByVal inherit As Boolean) As Object()
            Return New Object(0  - 1) {}
        End Function

        Public Overrides Function GetGetMethod(ByVal nonPublic As Boolean) As MethodInfo
            Return Me.getMethod
        End Function

        Public Overrides Function GetIndexParameters() As ParameterInfo()
            If (Not Me.getMethod Is Nothing) Then
                Return Me.getMethod.GetParameters
            End If
            If (Not Me.originalPropertyInfo Is Nothing) Then
                Return Me.originalPropertyInfo.GetIndexParameters
            End If
            Return New ParameterInfo(0  - 1) {}
        End Function

        Public Overrides Function GetSetMethod(ByVal nonPublic As Boolean) As MethodInfo
            Return Me.setMethod
        End Function

        Public Overrides Function GetValue(ByVal obj As Object, ByVal invokeAttr As BindingFlags, ByVal binder As Binder, ByVal index As Object(), ByVal culture As CultureInfo) As Object
            If ((Me.getMethod Is Nothing) AndAlso ((Me.originalPropertyInfo Is Nothing) OrElse Not Me.originalPropertyInfo.CanRead)) Then
                Throw New InvalidOperationException(SR.GetString("Error_PropertyHasNoGetterDefined", New Object() { Me.propertyName }))
            End If
            If (Not Me.getMethod Is Nothing) Then
                Return Me.getMethod.Invoke(obj, invokeAttr, binder, index, culture)
            End If
            Return Me.originalPropertyInfo.GetValue(obj, invokeAttr, binder, index, culture)
        End Function

        Public Overrides Function IsDefined(ByVal attributeType As Type, ByVal inherit As Boolean) As Boolean
            Throw New NotSupportedException
        End Function

        Public Overrides Sub SetValue(ByVal obj As Object, ByVal value As Object, ByVal invokeAttr As BindingFlags, ByVal binder As Binder, ByVal index As Object(), ByVal culture As CultureInfo)
            If ((Me.setMethod Is Nothing) AndAlso ((Me.originalPropertyInfo Is Nothing) OrElse Not Me.originalPropertyInfo.CanWrite)) Then
                Throw New InvalidOperationException(SR.GetString("Error_PropertyHasNoSetterDefined", New Object() { Me.propertyName }))
            End If
            If (Not Me.setMethod Is Nothing) Then
                Dim array As Object() = New Object((If((Not index Is Nothing), index.Length, 0) + 1)  - 1) {}
                array(If((Not index Is Nothing), index.Length, 0)) = value
                If (Not index Is Nothing) Then
                    index.CopyTo(array, 0)
                End If
                Me.setMethod.Invoke(obj, invokeAttr, binder, array, culture)
            Else
                Me.originalPropertyInfo.SetValue(obj, value, invokeAttr, binder, index, culture)
            End If
        End Sub


        ' Properties
        Public Overrides ReadOnly Property Attributes As PropertyAttributes
            Get
                Return PropertyAttributes.None
            End Get
        End Property

        Public Overrides ReadOnly Property CanRead As Boolean
            Get
                Return ((Not Me.getMethod Is Nothing) OrElse ((Not Me.originalPropertyInfo Is Nothing) AndAlso Me.originalPropertyInfo.CanRead))
            End Get
        End Property

        Public Overrides ReadOnly Property CanWrite As Boolean
            Get
                Return ((Not Me.setMethod Is Nothing) OrElse ((Not Me.originalPropertyInfo Is Nothing) AndAlso Me.originalPropertyInfo.CanWrite))
            End Get
        End Property

        Public Overrides ReadOnly Property DeclaringType As Type
            Get
                Return Me.declaringType
            End Get
        End Property

        Public Overrides ReadOnly Property Name As String
            Get
                Return Me.propertyName
            End Get
        End Property

        Public Overrides ReadOnly Property PropertyType As Type
            Get
                If (Not Me.getMethod Is Nothing) Then
                    Return Me.getMethod.ReturnType
                End If
                If (Not Me.originalPropertyInfo Is Nothing) Then
                    Return Me.originalPropertyInfo.PropertyType
                End If
                Return GetType(Object)
            End Get
        End Property

        Public Overrides ReadOnly Property ReflectedType As Type
            Get
                Return Me.declaringType
            End Get
        End Property


        ' Fields
        Private declaringType As Type
        Private getMethod As MethodInfo
        Private originalPropertyInfo As PropertyInfo
        Private propertyName As String
        Private setMethod As MethodInfo
    End Class
End Namespace

